{
 "nbformat": 4,
 "nbformat_minor": 0,
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zAc030sSPTcg"
   },
   "source": [
    "# Elastic's Recipe: Smarter Orders with Phi-3 small models\n",
    "\n",
    "In this notebook we will learn how to deploy [phi-3](https://azure.microsoft.com/en-us/products/phi-3) models on [Azure AI Studio](https://ai.azure.com) and using them with Elastic Open Inference Service to create a RAG application. This notebook illustrates the article [Elastic's Recipe: Smarter Orders with Phi-3 small models](https://www.elastic.co/search-labs/blog/utilizing-phi3-models).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Mw_0H4UdPTch"
   },
   "source": [
    "## Install packages and import necessary modules\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "i-tSzrSOPTch",
    "outputId": "fb751e6f-452e-4483-eb27-e4e0292e14bd"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Collecting elasticsearch==8.14\n",
      "  Downloading elasticsearch-8.14.0-py3-none-any.whl (480 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m480.2/480.2 kB\u001b[0m \u001b[31m7.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hCollecting elastic-transport<9,>=8.13 (from elasticsearch==8.14)\n",
      "  Downloading elastic_transport-8.13.1-py3-none-any.whl (64 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m64.5/64.5 kB\u001b[0m \u001b[31m7.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: urllib3<3,>=1.26.2 in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8.13->elasticsearch==8.14) (2.0.7)\n",
      "Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from elastic-transport<9,>=8.13->elasticsearch==8.14) (2024.7.4)\n",
      "Installing collected packages: elastic-transport, elasticsearch\n",
      "Successfully installed elastic-transport-8.13.1 elasticsearch-8.14.0\n"
     ]
    }
   ],
   "source": [
    "# install packages\n",
    "!python3 -m pip install elasticsearch==8.14\n",
    "\n",
    "from elasticsearch import Elasticsearch, exceptions\n",
    "from elasticsearch.helpers import bulk\n",
    "from getpass import getpass\n",
    "import json"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "T5LcXXq8PTci"
   },
   "source": [
    "## Declaring variables\n",
    "\n",
    "This code will create inputs where you can enter your credentials.\n",
    "\n",
    "Here you can learn how to retrieve your Elasticsearch credentials: [Finding Your Cloud ID](https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud#finding-your-cloud-id).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "FOWmTbENPTci",
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "outputId": "5f4d9844-36be-49b3-befb-ea9e31cac3cb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Elastic Cloud ID: ··········\n",
      "Elastic Api Key: ··········\n",
      "Azure API Key: ··········\n",
      "Azure target URL: ··········\n"
     ]
    }
   ],
   "source": [
    "ELASTIC_CLUSTER_ID = getpass(\"Elastic Cloud ID: \")\n",
    "ELASTIC_API_KEY = getpass(\"Elastic Api Key: \")\n",
    "\n",
    "AZURE_API_KEY = getpass(\"Azure API Key: \")\n",
    "AZURE_TARGET_URL = getpass(\"Azure target URL: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LUtoUYmvPTci"
   },
   "source": [
    "## Instance Elasticsearch client\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "nFWWL-OvPTci"
   },
   "outputs": [],
   "source": [
    "es_client = Elasticsearch(\n",
    "    cloud_id=ELASTIC_CLUSTER_ID,\n",
    "    api_key=ELASTIC_API_KEY,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_ojH6mlMPTci"
   },
   "source": [
    "## Creating embeddings endpoint\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Mfj9isXDPTcj",
    "outputId": "21bdca0a-2d26-4f48-c5a6-7fc49307634d"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Embedding endpoint created successfully.\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    es_client.options(\n",
    "        request_timeout=60, max_retries=3, retry_on_timeout=True\n",
    "    ).inference.put_model(\n",
    "        task_type=\"sparse_embedding\",\n",
    "        inference_id=\"elser-embeddings\",\n",
    "        body={\n",
    "            \"service\": \"elser\",\n",
    "            \"service_settings\": {\n",
    "                \"num_allocations\": 1,\n",
    "                \"num_threads\": 1,\n",
    "            },\n",
    "        },\n",
    "    )\n",
    "\n",
    "    print(\"Embedding endpoint created successfully.\")\n",
    "except exceptions.BadRequestError as e:\n",
    "    if e.error == \"resource_already_exists_exception\":\n",
    "        print(\"Embedding endpoint already created.\")\n",
    "    else:\n",
    "        raise e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "sUQwVQOCPTcj"
   },
   "source": [
    "## Creating completion endpoint\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 221
    },
    "id": "hu1jrgHYPTcj",
    "outputId": "87860da8-0a3d-4378-a392-ed760ae5159f"
   },
   "outputs": [
    {
     "output_type": "error",
     "ename": "NameError",
     "evalue": "name 'AZURE_API_KEY' is not defined",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-92-363fb39672e8>\u001b[0m in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      8\u001b[0m             \u001b[0;34m\"service\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m\"azureaistudio\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m             \"service_settings\": {\n\u001b[0;32m---> 10\u001b[0;31m                 \u001b[0;34m\"api_key\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAZURE_API_KEY\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     11\u001b[0m                 \u001b[0;34m\"target\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAZURE_TARGET_URL\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m                 \u001b[0;34m\"provider\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m\"microsoft_phi\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'AZURE_API_KEY' is not defined"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    es_client.options(\n",
    "        request_timeout=60, max_retries=3, retry_on_timeout=True\n",
    "    ).inference.put_model(\n",
    "        task_type=\"completion\",\n",
    "        inference_id=\"phi3-completion\",\n",
    "        body={\n",
    "            \"service\": \"azureaistudio\",\n",
    "            \"service_settings\": {\n",
    "                \"api_key\": AZURE_API_KEY,\n",
    "                \"target\": AZURE_TARGET_URL,\n",
    "                \"provider\": \"microsoft_phi\",\n",
    "                \"endpoint_type\": \"token\",\n",
    "            },\n",
    "        },\n",
    "    )\n",
    "    print(\"Completion endpoint created successfully\")\n",
    "except exceptions.BadRequestError as e:\n",
    "    if e.error == \"resource_already_exists_exception\":\n",
    "        print(\"Completion endpoint already created.\")\n",
    "    else:\n",
    "        raise e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "npXIeebePTcj"
   },
   "source": [
    "## Creating index\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "_m83KNhGPTcj"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    es_client.indices.create(\n",
    "        index=\"lasticco-menu\",\n",
    "        body={\n",
    "            \"mappings\": {\n",
    "                \"properties\": {\n",
    "                    \"code\": {\"type\": \"keyword\"},\n",
    "                    \"title\": {\"type\": \"text\"},\n",
    "                    \"description\": {\n",
    "                        \"type\": \"semantic_text\",\n",
    "                        \"inference_id\": \"elser-embeddings\",\n",
    "                    },\n",
    "                    \"price\": {\"type\": \"double\"},\n",
    "                    \"customizations\": {\"type\": \"object\"},\n",
    "                }\n",
    "            }\n",
    "        },\n",
    "    )\n",
    "except exceptions.RequestError as e:\n",
    "    if e.error == \"resource_already_exists_exception\":\n",
    "        print(\"Index already exists.\")\n",
    "    else:\n",
    "        raise e"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4nKofwOpPTcj"
   },
   "source": [
    "## Indexing data\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "nXABRpw6PTcj"
   },
   "outputs": [],
   "source": [
    "menu_dishes = [\n",
    "    {\n",
    "        \"code\": \"carbonara\",\n",
    "        \"title\": \"Pasta Carbonara\",\n",
    "        \"description\": \"Pasta Carbonara \\n Perfectly al dente spaghetti enrobed in a velvety sauce of farm-fresh eggs, aged Pecorino Romano, and smoky guanciale. Finished with a kiss of cracked black pepper for a classic Roman indulgence.\",\n",
    "        \"price\": 14.99,\n",
    "        \"customizations\": {\n",
    "            \"vegetarian\": [True, False],\n",
    "            \"cream\": [True, False],\n",
    "            \"extras\": [\"cheese\", \"garlic\", \"ham\"],\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"code\": \"alfredo\",\n",
    "        \"title\": \"Chicken Alfredo\",\n",
    "        \"description\": \"Chicken Alfredo \\n Recipe includes golden pan-fried seasoned chicken breasts and tender fettuccine, coated in the most dreamy cream sauce ever, coated with a velvety garlic and Parmesan cream sauce.\",\n",
    "        \"price\": 18.99,\n",
    "        \"customizations\": {\n",
    "            \"vegetarian\": [True, False],\n",
    "            \"cream\": [True, False],\n",
    "            \"extras\": [\"cheese\", \"onions\", \"olives\"],\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"code\": \"gnocchi\",\n",
    "        \"title\": \"Four Cheese Gnocchi\",\n",
    "        \"description\": \"Four Cheese Gnocchi \\n soft pillowy potato gnocchi coated in a silken cheesy sauce made of four different cheeses: Gouda, Parmigiano, Brie, and the star, Gorgonzola. The combination of four different types of cheese will make your tastebuds dance for joy.\",\n",
    "        \"price\": 15.99,\n",
    "        \"customizations\": {\n",
    "            \"vegetarian\": [True, False],\n",
    "            \"cream\": [True, False],\n",
    "            \"extras\": [\"cheese\", \"bacon\", \"mushrooms\"],\n",
    "        },\n",
    "    },\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "kdzyWISlPTcj",
    "outputId": "1380c145-4595-46b9-c530-54d679bad85d"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Data indexed successfully.\n"
     ]
    }
   ],
   "source": [
    "# This function will create a bulk object for the given id and body\n",
    "def build_bulk_obj(id, body):\n",
    "    return {\"_index\": \"lasticco-menu\", \"_id\": id, \"_source\": body}\n",
    "\n",
    "\n",
    "data = []\n",
    "\n",
    "# Constructing bulk object for each dish\n",
    "for i, dish in enumerate(menu_dishes):\n",
    "    data.append(build_bulk_obj(i + 1, dish))\n",
    "\n",
    "try:\n",
    "    # Using the bulk API to index the data\n",
    "    bulk(es_client, data)\n",
    "    print(\"Data indexed successfully.\")\n",
    "except exceptions.RequestError as e:\n",
    "    print(\"Error indexing data.\")\n",
    "    print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Retrieving relevant dishes\n",
    "\n",
    "We use a semantic query to retrieve the most relevant dishes based on the customer request."
   ],
   "metadata": {
    "id": "8cR-wbkthqv7"
   }
  },
  {
   "cell_type": "code",
   "source": [
    "try:\n",
    "    response = es_client.search(\n",
    "        index=\"lasticco-menu\",\n",
    "        body={\n",
    "            \"query\": {\n",
    "                \"semantic\": {\n",
    "                    \"field\": \"description\",\n",
    "                    \"query\": \"may I have a carbonara with cream and bacon?\",\n",
    "                }\n",
    "            },\n",
    "        },\n",
    "    )\n",
    "    dishes = []\n",
    "\n",
    "    for r in response.body[\"hits\"][\"hits\"]:\n",
    "        dishes.append(r[\"_source\"])\n",
    "\n",
    "    print(f\"Response: {json.dumps(dishes, indent=2)}\")\n",
    "except Exception as e:\n",
    "    print(e)"
   ],
   "metadata": {
    "id": "AAOwqHT8iEbl",
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "outputId": "5ff04454-ae43-401c-d3fc-747c5d8bec7c"
   },
   "execution_count": null,
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Response: [\n",
      "  {\n",
      "    \"code\": \"carbonara\",\n",
      "    \"price\": 14.99,\n",
      "    \"description\": {\n",
      "      \"text\": \"Pasta Carbonara \\n Perfectly al dente spaghetti enrobed in a velvety sauce of farm-fresh eggs, aged Pecorino Romano, and smoky guanciale. Finished with a kiss of cracked black pepper for a classic Roman indulgence.\",\n",
      "      \"inference\": {\n",
      "        \"inference_id\": \"elser-embeddings\",\n",
      "        \"model_settings\": {\n",
      "          \"task_type\": \"sparse_embedding\"\n",
      "        },\n",
      "        \"chunks\": [\n",
      "          {\n",
      "            \"text\": \"Pasta Carbonara \\n Perfectly al dente spaghetti enrobed in a velvety sauce of farm-fresh eggs, aged Pecorino Romano, and smoky guanciale. Finished with a kiss of cracked black pepper for a classic Roman indulgence.\",\n",
      "            \"embeddings\": {\n",
      "              \"carbon\": 2.0847998,\n",
      "              \"pasta\": 2.0838325,\n",
      "              \"spaghetti\": 1.9527067,\n",
      "              \"##ara\": 1.7632319,\n",
      "              \"romano\": 1.6877614,\n",
      "              \"al\": 1.6518246,\n",
      "              \"dent\": 1.5832088,\n",
      "              \"roman\": 1.5785156,\n",
      "              \"sauce\": 1.50039,\n",
      "              \"eggs\": 1.4797868,\n",
      "              \"velvet\": 1.4146874,\n",
      "              \"##cial\": 1.3529263,\n",
      "              \"smoky\": 1.3520736,\n",
      "              \"##ro\": 1.3192937,\n",
      "              \"egg\": 1.3167425,\n",
      "              \"kiss\": 1.3027223,\n",
      "              \"cracked\": 1.278348,\n",
      "              \"pepper\": 1.2271707,\n",
      "              \"farm\": 1.2113343,\n",
      "              \"alfredo\": 1.1915079,\n",
      "              \"gu\": 1.190911,\n",
      "              \"noodles\": 1.1808913,\n",
      "              \"italian\": 1.1601502,\n",
      "              \"fresh\": 1.1369088,\n",
      "              \"##cor\": 1.0747697,\n",
      "              \"pe\": 1.0703862,\n",
      "              \"classic\": 1.0423423,\n",
      "              \"rome\": 1.0119383,\n",
      "              \"flavor\": 0.9328391,\n",
      "              \"peppers\": 0.9042534,\n",
      "              \"##aro\": 0.8550794,\n",
      "              \"en\": 0.8329167,\n",
      "              \"##an\": 0.8324837,\n",
      "              \"black\": 0.8178875,\n",
      "              \"smoke\": 0.79119015,\n",
      "              \"italy\": 0.74483544,\n",
      "              \"##ino\": 0.72506446,\n",
      "              \"tomato\": 0.71198094,\n",
      "              \"perfectly\": 0.68112665,\n",
      "              \"ingredients\": 0.6761448,\n",
      "              \"ravi\": 0.6460934,\n",
      "              \"finished\": 0.6169553,\n",
      "              \"recipe\": 0.58733445,\n",
      "              \"perfect\": 0.57436633,\n",
      "              \"aged\": 0.5583758,\n",
      "              \"taste\": 0.52448153,\n",
      "              \"shrimp\": 0.5087635,\n",
      "              \"cave\": 0.50867414,\n",
      "              \"blend\": 0.50848633,\n",
      "              \"wine\": 0.50275457,\n",
      "              \"romans\": 0.49936667,\n",
      "              \"spice\": 0.49755874,\n",
      "              \"squash\": 0.4949674,\n",
      "              \"dinner\": 0.4923304,\n",
      "              \"cheese\": 0.4829378,\n",
      "              \"flavour\": 0.457689,\n",
      "              \"##gence\": 0.45691547,\n",
      "              \"flat\": 0.4553697,\n",
      "              \"crack\": 0.45347178,\n",
      "              \"mario\": 0.4526796,\n",
      "              \"rice\": 0.45201895,\n",
      "              \"au\": 0.4349133,\n",
      "              \"traditional\": 0.43312475,\n",
      "              \"made\": 0.4282039,\n",
      "              \"bone\": 0.42157665,\n",
      "              \"cake\": 0.4134516,\n",
      "              \"chile\": 0.3934753,\n",
      "              \"pearl\": 0.38652605,\n",
      "              \"soup\": 0.3570259,\n",
      "              \"salmon\": 0.3496939,\n",
      "              \"ar\": 0.34654406,\n",
      "              \"varieties\": 0.3456518,\n",
      "              \"crushed\": 0.33395255,\n",
      "              \"spanish\": 0.31545156,\n",
      "              \"salad\": 0.31005082,\n",
      "              \"dessert\": 0.30972683,\n",
      "              \"style\": 0.30488467,\n",
      "              \"quality\": 0.30363235,\n",
      "              \"all\": 0.30355245,\n",
      "              \"dish\": 0.29586068,\n",
      "              \"tomatoes\": 0.28619272,\n",
      "              \"food\": 0.28274676,\n",
      "              \"type\": 0.2670385,\n",
      "              \"finish\": 0.26572567,\n",
      "              \"fiery\": 0.26413622,\n",
      "              \"marble\": 0.26305264,\n",
      "              \"stuffing\": 0.26177517,\n",
      "              \"meat\": 0.25015828,\n",
      "              \"foods\": 0.24370497,\n",
      "              \"cas\": 0.24352334,\n",
      "              \"sour\": 0.23882519,\n",
      "              \"delicious\": 0.23850876,\n",
      "              \"latin\": 0.23436877,\n",
      "              \"mafia\": 0.22955851,\n",
      "              \"##che\": 0.22312142,\n",
      "              \"tennessee\": 0.22106534,\n",
      "              \"dried\": 0.21666816,\n",
      "              \"co\": 0.21655259,\n",
      "              \"aluminum\": 0.2090411,\n",
      "              \"doubt\": 0.19801831,\n",
      "              \"pancakes\": 0.19658157,\n",
      "              \"thick\": 0.19645111,\n",
      "              \"favorite\": 0.18269683,\n",
      "              \"restaurant\": 0.18210879,\n",
      "              \"pure\": 0.17537574,\n",
      "              \"polish\": 0.1739754,\n",
      "              \"cooking\": 0.17368133,\n",
      "              \"fish\": 0.1716123,\n",
      "              \"pizza\": 0.17020135,\n",
      "              \"pit\": 0.15634274,\n",
      "              \"mix\": 0.15507321,\n",
      "              \"chef\": 0.14697866,\n",
      "              \"spicy\": 0.14347146,\n",
      "              \"shape\": 0.1367214,\n",
      "              \"old\": 0.13251224,\n",
      "              \"drink\": 0.13050945,\n",
      "              \"anti\": 0.13011442,\n",
      "              \"ripe\": 0.12922636,\n",
      "              \"garlic\": 0.12443257,\n",
      "              \"rich\": 0.11953975,\n",
      "              \"ara\": 0.10267873,\n",
      "              \"with\": 0.10157385,\n",
      "              \"##o\": 0.09824008,\n",
      "              \"lump\": 0.09293696,\n",
      "              \"sicilian\": 0.08502127,\n",
      "              \"##e\": 0.083423816,\n",
      "              \"substitute\": 0.080164224,\n",
      "              \"texture\": 0.07978093,\n",
      "              \"##chi\": 0.07787835,\n",
      "              \"rico\": 0.077181816,\n",
      "              \"castle\": 0.060185388,\n",
      "              \"c\": 0.05781913,\n",
      "              \"tara\": 0.054664496,\n",
      "              \"milo\": 0.046940666,\n",
      "              \"chicken\": 0.037327815,\n",
      "              \"sa\": 0.03659888,\n",
      "              \"##ante\": 0.027901433,\n",
      "              \"mass\": 0.026733113,\n",
      "              \"##ato\": 0.026702356,\n",
      "              \"milan\": 0.024935864,\n",
      "              \"greek\": 0.02269474,\n",
      "              \"combination\": 0.020557316,\n",
      "              \"elegant\": 0.014001829,\n",
      "              \"bread\": 0.012648127,\n",
      "              \"argentina\": 0.011897084,\n",
      "              \"flavors\": 0.010257504,\n",
      "              \"tuna\": 0.009524028,\n",
      "              \"roma\": 0.0055943117,\n",
      "              \"__\": 0.002049847,\n",
      "              \"a\": 0.00012992969\n",
      "            }\n",
      "          }\n",
      "        ]\n",
      "      }\n",
      "    },\n",
      "    \"title\": \"Pasta Carbonara\",\n",
      "    \"customizations\": {\n",
      "      \"vegetarian\": [\n",
      "        true,\n",
      "        false\n",
      "      ],\n",
      "      \"extras\": [\n",
      "        \"cheese\",\n",
      "        \"garlic\",\n",
      "        \"ham\"\n",
      "      ],\n",
      "      \"cream\": [\n",
      "        true,\n",
      "        false\n",
      "      ]\n",
      "    }\n",
      "  },\n",
      "  {\n",
      "    \"code\": \"alfredo\",\n",
      "    \"price\": 18.99,\n",
      "    \"description\": {\n",
      "      \"text\": \"Chicken Alfredo \\n Recipe includes golden pan-fried seasoned chicken breasts and tender fettuccine, coated in the most dreamy cream sauce ever, coated with a velvety garlic and Parmesan cream sauce.\",\n",
      "      \"inference\": {\n",
      "        \"inference_id\": \"elser-embeddings\",\n",
      "        \"model_settings\": {\n",
      "          \"task_type\": \"sparse_embedding\"\n",
      "        },\n",
      "        \"chunks\": [\n",
      "          {\n",
      "            \"text\": \"Chicken Alfredo \\n Recipe includes golden pan-fried seasoned chicken breasts and tender fettuccine, coated in the most dreamy cream sauce ever, coated with a velvety garlic and Parmesan cream sauce.\",\n",
      "            \"embeddings\": {\n",
      "              \"alfredo\": 2.564587,\n",
      "              \"chicken\": 1.8346423,\n",
      "              \"pasta\": 1.8238221,\n",
      "              \"##ucci\": 1.6461563,\n",
      "              \"sauce\": 1.6025357,\n",
      "              \"recipe\": 1.4776391,\n",
      "              \"fried\": 1.4650584,\n",
      "              \"breasts\": 1.4406543,\n",
      "              \"cream\": 1.4403517,\n",
      "              \"golden\": 1.3249015,\n",
      "              \"##tt\": 1.3037602,\n",
      "              \"pan\": 1.298015,\n",
      "              \"garlic\": 1.2871181,\n",
      "              \"seasoned\": 1.196314,\n",
      "              \"italian\": 1.1623968,\n",
      "              \"velvet\": 1.1578108,\n",
      "              \"dream\": 1.1535012,\n",
      "              \"breast\": 1.1374456,\n",
      "              \"chickens\": 1.1048578,\n",
      "              \"flavor\": 1.0701971,\n",
      "              \"fry\": 0.9859959,\n",
      "              \"tender\": 0.9708918,\n",
      "              \"##mes\": 0.9217419,\n",
      "              \"recipes\": 0.8933892,\n",
      "              \"most\": 0.7819251,\n",
      "              \"##an\": 0.7673652,\n",
      "              \"ingredients\": 0.74734217,\n",
      "              \"fe\": 0.7179425,\n",
      "              \"stuffing\": 0.7053486,\n",
      "              \"coating\": 0.66489476,\n",
      "              \"ever\": 0.6408478,\n",
      "              \"soup\": 0.6342612,\n",
      "              \"restaurant\": 0.59911627,\n",
      "              \"shrimp\": 0.57749015,\n",
      "              \"cooked\": 0.56963134,\n",
      "              \"onion\": 0.5450308,\n",
      "              \"spice\": 0.533965,\n",
      "              \"gold\": 0.5305381,\n",
      "              \"##ula\": 0.52431905,\n",
      "              \"coated\": 0.52246696,\n",
      "              \"romano\": 0.51953495,\n",
      "              \"dinner\": 0.5152075,\n",
      "              \"cooking\": 0.50969106,\n",
      "              \"flavour\": 0.50816065,\n",
      "              \"par\": 0.4996068,\n",
      "              \"noodles\": 0.49789834,\n",
      "              \"kitchen\": 0.4947274,\n",
      "              \"best\": 0.4874154,\n",
      "              \"##scan\": 0.478875,\n",
      "              \"wings\": 0.4663816,\n",
      "              \"rice\": 0.46338895,\n",
      "              \"coat\": 0.46131432,\n",
      "              \"dish\": 0.4605129,\n",
      "              \"cake\": 0.45159337,\n",
      "              \"wing\": 0.4267126,\n",
      "              \"campbell\": 0.42100388,\n",
      "              \"##nta\": 0.41588247,\n",
      "              \"type\": 0.41289526,\n",
      "              \"combination\": 0.41191906,\n",
      "              \"mixing\": 0.40398732,\n",
      "              \"food\": 0.4006494,\n",
      "              \"julia\": 0.3836181,\n",
      "              \"delicate\": 0.38125896,\n",
      "              \"italy\": 0.38078514,\n",
      "              \"taste\": 0.38036105,\n",
      "              \"pisa\": 0.3761185,\n",
      "              \"don\": 0.37580723,\n",
      "              \"pancakes\": 0.36829042,\n",
      "              \"foods\": 0.36580428,\n",
      "              \"##y\": 0.34617537,\n",
      "              \"chef\": 0.34488603,\n",
      "              \"fra\": 0.34359822,\n",
      "              \"stuffed\": 0.34257597,\n",
      "              \"spanish\": 0.3421706,\n",
      "              \"crisp\": 0.34053022,\n",
      "              \"blend\": 0.3373403,\n",
      "              \"cook\": 0.31444147,\n",
      "              \"substitute\": 0.31359094,\n",
      "              \"technique\": 0.3106372,\n",
      "              \"surrounded\": 0.2964942,\n",
      "              \"pepper\": 0.2922128,\n",
      "              \"thick\": 0.27548715,\n",
      "              \"served\": 0.25957543,\n",
      "              \"formula\": 0.25705764,\n",
      "              \"texture\": 0.2544215,\n",
      "              \"fries\": 0.24249437,\n",
      "              \"include\": 0.23216493,\n",
      "              \"style\": 0.22883052,\n",
      "              \"dessert\": 0.22751497,\n",
      "              \"thighs\": 0.22610186,\n",
      "              \"wine\": 0.22608131,\n",
      "              \"sweet\": 0.22575645,\n",
      "              \"cheese\": 0.2197249,\n",
      "              \"delicious\": 0.21336219,\n",
      "              \"soy\": 0.21156286,\n",
      "              \"##uo\": 0.21134749,\n",
      "              \"chili\": 0.20474188,\n",
      "              \"pope\": 0.20450474,\n",
      "              \"rich\": 0.20416267,\n",
      "              \"made\": 0.20068921,\n",
      "              \"with\": 0.19718379,\n",
      "              \"ling\": 0.19635552,\n",
      "              \"spices\": 0.18753126,\n",
      "              \"stir\": 0.18500854,\n",
      "              \"minute\": 0.17656763,\n",
      "              \"anna\": 0.1724526,\n",
      "              \"milk\": 0.16676955,\n",
      "              \"creamy\": 0.1629867,\n",
      "              \"battered\": 0.15504432,\n",
      "              \"fish\": 0.1532438,\n",
      "              \"favorite\": 0.15209308,\n",
      "              \"jose\": 0.14888714,\n",
      "              \"meat\": 0.14689654,\n",
      "              \"mix\": 0.14603789,\n",
      "              \"spicy\": 0.13331048,\n",
      "              \"skill\": 0.13055632,\n",
      "              \"french\": 0.12478566,\n",
      "              \"wonderful\": 0.11361911,\n",
      "              \"ross\": 0.1104974,\n",
      "              \"elise\": 0.11042087,\n",
      "              \"basil\": 0.104210526,\n",
      "              \"mexican\": 0.09911397,\n",
      "              \"pizza\": 0.09332448,\n",
      "              \"fill\": 0.09031643,\n",
      "              \"##mbo\": 0.088501684,\n",
      "              \"package\": 0.08747048,\n",
      "              \"includes\": 0.08606179,\n",
      "              \"##ko\": 0.08545729,\n",
      "              \"f\": 0.08135256,\n",
      "              \"fond\": 0.08125717,\n",
      "              \"features\": 0.06959614,\n",
      "              \"##o\": 0.06385035,\n",
      "              \"shell\": 0.062879145,\n",
      "              \"dreams\": 0.060527902,\n",
      "              \"bones\": 0.058741644,\n",
      "              \"##ull\": 0.057891022,\n",
      "              \"ari\": 0.054450814,\n",
      "              \"cod\": 0.052321326,\n",
      "              \"contain\": 0.051052306,\n",
      "              \"egg\": 0.049737327,\n",
      "              \"##ne\": 0.044573493,\n",
      "              \"##fu\": 0.043771666,\n",
      "              \"che\": 0.0429009,\n",
      "              \"prepared\": 0.040078502,\n",
      "              \"mayo\": 0.037097875,\n",
      "              \"is\": 0.035554122,\n",
      "              \"perfect\": 0.034818944,\n",
      "              \"sherry\": 0.03144467,\n",
      "              \"serve\": 0.02636094,\n",
      "              \"meal\": 0.0249497,\n",
      "              \"gu\": 0.014452303,\n",
      "              \"tu\": 0.013452006,\n",
      "              \"and\": 0.013005081,\n",
      "              \"ribs\": 0.012063167,\n",
      "              \"##cci\": 0.011064485,\n",
      "              \"add\": 0.010891278,\n",
      "              \"pat\": 0.0093868105,\n",
      "              \"ingredient\": 0.007957779,\n",
      "              \"crunch\": 0.0046977154,\n",
      "              \"butter\": 0.004236889\n",
      "            }\n",
      "          }\n",
      "        ]\n",
      "      }\n",
      "    },\n",
      "    \"title\": \"Chicken Alfredo\",\n",
      "    \"customizations\": {\n",
      "      \"vegetarian\": [\n",
      "        true,\n",
      "        false\n",
      "      ],\n",
      "      \"extras\": [\n",
      "        \"cheese\",\n",
      "        \"onions\",\n",
      "        \"olives\"\n",
      "      ],\n",
      "      \"cream\": [\n",
      "        true,\n",
      "        false\n",
      "      ]\n",
      "    }\n",
      "  },\n",
      "  {\n",
      "    \"code\": \"gnocchi\",\n",
      "    \"price\": 15.99,\n",
      "    \"description\": {\n",
      "      \"text\": \"Four Cheese Gnocchi \\n soft pillowy potato gnocchi coated in a silken cheesy sauce made of four different cheeses: Gouda, Parmigiano, Brie, and the star, Gorgonzola. The combination of four different types of cheese will make your tastebuds dance for joy.\",\n",
      "      \"inference\": {\n",
      "        \"inference_id\": \"elser-embeddings\",\n",
      "        \"model_settings\": {\n",
      "          \"task_type\": \"sparse_embedding\"\n",
      "        },\n",
      "        \"chunks\": [\n",
      "          {\n",
      "            \"text\": \"Four Cheese Gnocchi \\n soft pillowy potato gnocchi coated in a silken cheesy sauce made of four different cheeses: Gouda, Parmigiano, Brie, and the star, Gorgonzola. The combination of four different types of cheese will make your tastebuds dance for joy.\",\n",
      "            \"embeddings\": {\n",
      "              \"cheese\": 1.8433701,\n",
      "              \"##cchi\": 1.8249218,\n",
      "              \"pillow\": 1.7976478,\n",
      "              \"##uda\": 1.7632233,\n",
      "              \"##no\": 1.7160593,\n",
      "              \"sauce\": 1.6652024,\n",
      "              \"potato\": 1.6410445,\n",
      "              \"##rgo\": 1.5110843,\n",
      "              \"four\": 1.4945054,\n",
      "              \"star\": 1.4881107,\n",
      "              \"pillows\": 1.4633442,\n",
      "              \"g\": 1.4311051,\n",
      "              \"potatoes\": 1.4266229,\n",
      "              \"silk\": 1.3149087,\n",
      "              \"che\": 1.2663606,\n",
      "              \"##gia\": 1.2491798,\n",
      "              \"##nzo\": 1.2481608,\n",
      "              \"joy\": 1.2380968,\n",
      "              \"##ie\": 1.2244678,\n",
      "              \"soft\": 1.2166287,\n",
      "              \"br\": 1.1827679,\n",
      "              \"taste\": 1.1643262,\n",
      "              \"##mi\": 1.1231838,\n",
      "              \"dance\": 1.0761534,\n",
      "              \"##la\": 1.0627452,\n",
      "              \"4\": 1.0579926,\n",
      "              \"italian\": 1.0441946,\n",
      "              \"go\": 1.0375262,\n",
      "              \"stars\": 1.0235771,\n",
      "              \"##es\": 1.0135604,\n",
      "              \"combination\": 0.97541225,\n",
      "              \"made\": 0.9574184,\n",
      "              \"pasta\": 0.92463857,\n",
      "              \"coat\": 0.8985466,\n",
      "              \"coated\": 0.8865534,\n",
      "              \"types\": 0.8669388,\n",
      "              \"varieties\": 0.82150537,\n",
      "              \"flavor\": 0.79355574,\n",
      "              \"stuffed\": 0.78604937,\n",
      "              \"par\": 0.7816326,\n",
      "              \"coating\": 0.76706445,\n",
      "              \"squash\": 0.7433965,\n",
      "              \"romano\": 0.7269263,\n",
      "              \"cake\": 0.6953739,\n",
      "              \"vegetables\": 0.69372135,\n",
      "              \"italy\": 0.65606326,\n",
      "              \"type\": 0.6555585,\n",
      "              \"ingredients\": 0.6509747,\n",
      "              \"mario\": 0.61885077,\n",
      "              \"stuffing\": 0.5789762,\n",
      "              \"texture\": 0.5746486,\n",
      "              \"##tti\": 0.55706394,\n",
      "              \"vegetable\": 0.552092,\n",
      "              \"##na\": 0.53830713,\n",
      "              \"russ\": 0.53325486,\n",
      "              \"tuck\": 0.52827513,\n",
      "              \"dancing\": 0.5244148,\n",
      "              \"shape\": 0.5233079,\n",
      "              \"##cco\": 0.50105345,\n",
      "              \"foods\": 0.4941753,\n",
      "              \"brussels\": 0.488823,\n",
      "              \"flavour\": 0.48540276,\n",
      "              \"##gg\": 0.48222354,\n",
      "              \"food\": 0.44196266,\n",
      "              \"rice\": 0.4353299,\n",
      "              \"basket\": 0.4289376,\n",
      "              \"bacon\": 0.42317447,\n",
      "              \"recipe\": 0.42105818,\n",
      "              \"bell\": 0.4208563,\n",
      "              \"fuzzy\": 0.41236413,\n",
      "              \"fourth\": 0.41061163,\n",
      "              \"##ute\": 0.40760192,\n",
      "              \"surrounded\": 0.39993945,\n",
      "              \"brands\": 0.39929348,\n",
      "              \"soup\": 0.393992,\n",
      "              \"##ce\": 0.3913286,\n",
      "              \"different\": 0.38472915,\n",
      "              \"knife\": 0.3737238,\n",
      "              \"surprise\": 0.35915875,\n",
      "              \"##i\": 0.35583097,\n",
      "              \"pisa\": 0.34751344,\n",
      "              \"lump\": 0.3125717,\n",
      "              \"alfredo\": 0.31175232,\n",
      "              \"noodles\": 0.30807647,\n",
      "              \"no\": 0.2884717,\n",
      "              \"##so\": 0.2869589,\n",
      "              \"milk\": 0.285988,\n",
      "              \"genus\": 0.28054005,\n",
      "              \"foam\": 0.27264646,\n",
      "              \"brand\": 0.27150664,\n",
      "              \"blend\": 0.27041394,\n",
      "              \"velvet\": 0.26908088,\n",
      "              \"gu\": 0.26885387,\n",
      "              \"dish\": 0.2673401,\n",
      "              \"fish\": 0.26622063,\n",
      "              \"went\": 0.2660476,\n",
      "              \"colors\": 0.2594121,\n",
      "              \"carrot\": 0.24424857,\n",
      "              \"mascot\": 0.24353577,\n",
      "              \"##ura\": 0.23890406,\n",
      "              \"mushroom\": 0.2349561,\n",
      "              \"del\": 0.22825418,\n",
      "              \"covered\": 0.22789176,\n",
      "              \"plum\": 0.21863972,\n",
      "              \"make\": 0.21811977,\n",
      "              \"layer\": 0.19855213,\n",
      "              \"##s\": 0.19764976,\n",
      "              \"direction\": 0.19220816,\n",
      "              \"variants\": 0.1894919,\n",
      "              \"product\": 0.18020976,\n",
      "              \"happy\": 0.1766042,\n",
      "              \"slice\": 0.17476365,\n",
      "              \"##gur\": 0.17255041,\n",
      "              \"dessert\": 0.17195415,\n",
      "              \"dinner\": 0.16261624,\n",
      "              \"composed\": 0.16121463,\n",
      "              \"these\": 0.156481,\n",
      "              \"__\": 0.1550779,\n",
      "              \"##bu\": 0.15405245,\n",
      "              \"combine\": 0.14674234,\n",
      "              \"flavors\": 0.14650504,\n",
      "              \"sweet\": 0.14420816,\n",
      "              \"mixing\": 0.14227036,\n",
      "              \"waltz\": 0.1328341,\n",
      "              \"layered\": 0.13259411,\n",
      "              \"##ata\": 0.13255036,\n",
      "              \"pastry\": 0.13126214,\n",
      "              \"##ese\": 0.12905255,\n",
      "              \"##oli\": 0.12838961,\n",
      "              \"bread\": 0.12678272,\n",
      "              \"shapes\": 0.12635648,\n",
      "              \"bed\": 0.124999665,\n",
      "              \"combinations\": 0.12327213,\n",
      "              \"##zone\": 0.121784054,\n",
      "              \"mixture\": 0.12173065,\n",
      "              \"cushion\": 0.120557345,\n",
      "              \"parma\": 0.11741559,\n",
      "              \"dream\": 0.11702808,\n",
      "              \"easter\": 0.116614416,\n",
      "              \"layers\": 0.113192976,\n",
      "              \"milan\": 0.11088159,\n",
      "              \"couch\": 0.10817721,\n",
      "              \"stir\": 0.10738166,\n",
      "              \"##hi\": 0.10468957,\n",
      "              \"came\": 0.099799715,\n",
      "              \"##y\": 0.09693489,\n",
      "              \"hill\": 0.09482902,\n",
      "              \"bubble\": 0.094252035,\n",
      "              \"herb\": 0.093428716,\n",
      "              \"bag\": 0.090363264,\n",
      "              \"cover\": 0.0852456,\n",
      "              \"dip\": 0.08419295,\n",
      "              \"fruit\": 0.07581491,\n",
      "              \"hawk\": 0.074430756,\n",
      "              \"with\": 0.07412828,\n",
      "              \"size\": 0.0740002,\n",
      "              \"famous\": 0.07191443,\n",
      "              \"thick\": 0.071299866,\n",
      "              \"nap\": 0.070573956,\n",
      "              \"riga\": 0.06961849,\n",
      "              \"fluffy\": 0.06866412,\n",
      "              \"pile\": 0.06759319,\n",
      "              \"slip\": 0.055408016,\n",
      "              \"onion\": 0.051355843,\n",
      "              \"rocco\": 0.05095171,\n",
      "              \"##zo\": 0.050170857,\n",
      "              \"della\": 0.049794152,\n",
      "              \"##zza\": 0.046903927,\n",
      "              \"graz\": 0.046479788,\n",
      "              \"crisp\": 0.042849854,\n",
      "              \"gr\": 0.04122299,\n",
      "              \"fried\": 0.04042843,\n",
      "              \"rome\": 0.03976339,\n",
      "              \"##rella\": 0.039447036,\n",
      "              \"garlic\": 0.03556574,\n",
      "              \"softness\": 0.033182874,\n",
      "              \"come\": 0.032993965,\n",
      "              \"##uti\": 0.026017783,\n",
      "              \"pancakes\": 0.025654988,\n",
      "              \"cot\": 0.022374453,\n",
      "              \"##ach\": 0.022212872,\n",
      "              \"dressing\": 0.020076636,\n",
      "              \"shrimp\": 0.017028434,\n",
      "              \"illusion\": 0.016683934,\n",
      "              \"rattle\": 0.01558036,\n",
      "              \"##en\": 0.015386687,\n",
      "              \"monster\": 0.014637346,\n",
      "              \"firm\": 0.013829836,\n",
      "              \"##rino\": 0.01207577,\n",
      "              \"toro\": 0.011723079,\n",
      "              \"bud\": 0.011340208,\n",
      "              \"cute\": 0.0075798524,\n",
      "              \"stuff\": 0.003842591\n",
      "            }\n",
      "          }\n",
      "        ]\n",
      "      }\n",
      "    },\n",
      "    \"title\": \"Four Cheese Gnocchi\",\n",
      "    \"customizations\": {\n",
      "      \"vegetarian\": [\n",
      "        true,\n",
      "        false\n",
      "      ],\n",
      "      \"extras\": [\n",
      "        \"cheese\",\n",
      "        \"bacon\",\n",
      "        \"mushrooms\"\n",
      "      ],\n",
      "      \"cream\": [\n",
      "        true,\n",
      "        false\n",
      "      ]\n",
      "    }\n",
      "  }\n",
      "]\n"
     ]
    }
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Jo3OxFT3PTcj"
   },
   "source": [
    "### Putting everything together\n",
    "\n",
    "With this script we can ask the user to order, and keep the status of the order updated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Pk0ttelOPTcj",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "outputId": "55f6ede9-e15d-4353-99e5-f6f1d69f0478"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "What would you like to order? pasta with cheese\n",
      "Result: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n",
      "The current order status is: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n",
      "What would you like to order? alfredo\n",
      "Result: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"alfredo\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": []\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n",
      "The current order status is: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"alfredo\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": []\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n",
      "What would you like to order? another carbonara with extra cheese\n",
      "Result: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"alfredo\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": []\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n",
      "The current order status is: \n",
      " {\n",
      "  \"order\": [\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"alfredo\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": []\n",
      "    },\n",
      "    {\n",
      "      \"code\": \"carbonara\",\n",
      "      \"qty\": 1,\n",
      "      \"customizations\": [\n",
      "        {\n",
      "          \"extras\": [\n",
      "            \"cheese\"\n",
      "          ]\n",
      "        }\n",
      "      ]\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "\n"
     ]
    },
    {
     "output_type": "error",
     "ename": "KeyboardInterrupt",
     "evalue": "Interrupted by user",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-12-5bfa92de7a4e>\u001b[0m in \u001b[0;36m<cell line: 3>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m     \u001b[0mquery\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"What would you like to order? \"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m     \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m    849\u001b[0m                 \u001b[0;34m\"raw_input was called, but this frontend does not support input requests.\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    850\u001b[0m             )\n\u001b[0;32m--> 851\u001b[0;31m         return self._input_request(str(prompt),\n\u001b[0m\u001b[1;32m    852\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    853\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_header\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m    893\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    894\u001b[0m                 \u001b[0;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 895\u001b[0;31m                 \u001b[0;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Interrupted by user\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    896\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    897\u001b[0m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid Message:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: Interrupted by user"
     ]
    }
   ],
   "source": [
    "current_order = {\"order\": []}\n",
    "\n",
    "while True:\n",
    "    query = input(\"What would you like to order? \")\n",
    "\n",
    "    try:\n",
    "        response = es_client.search(\n",
    "            index=\"lasticco-menu\",\n",
    "            body={\n",
    "                \"size\": 3,\n",
    "                \"_source\": {\"excludes\": [\"*embeddings\", \"*chunks\", \"*inference\"]},\n",
    "                \"query\": {\n",
    "                    \"semantic\": {\n",
    "                        \"field\": \"description\",\n",
    "                        \"query\": query,\n",
    "                    }\n",
    "                },\n",
    "            },\n",
    "        )\n",
    "\n",
    "        dishes = []\n",
    "\n",
    "        for r in response.body[\"hits\"][\"hits\"]:\n",
    "            dishes.append(r[\"_source\"])\n",
    "\n",
    "        # Build prompt\n",
    "        example_order = {\n",
    "            \"order\": [\n",
    "                {\n",
    "                    \"code\": \"carbonara\",\n",
    "                    \"qty\": 1,\n",
    "                    \"customizations\": [{\"vegetarian\": True}],\n",
    "                },\n",
    "                {\n",
    "                    \"code\": \"alfredo\",\n",
    "                    \"qty\": 2,\n",
    "                    \"customizations\": [{\"extras\": [\"cheese\"]}],\n",
    "                },\n",
    "                {\n",
    "                    \"code\": \"gnocchi\",\n",
    "                    \"qty\": 1,\n",
    "                    \"customizations\": [{\"extras\": [\"mushrooms\"]}],\n",
    "                },\n",
    "            ],\n",
    "        }\n",
    "\n",
    "        input_content = f\"\"\"\n",
    "            Your task is to manage an order based on the AVAILABLE DISHES in the MENU and the USER REQUEST. Follow these strict rules:\n",
    "\n",
    "              1. ONLY add dishes to the order that are explicitly listed in the MENU.\n",
    "              2. If the requested dish is not in the MENU, do not add anything to the order.\n",
    "              3. The response must always be a valid JSON object containing an \"order\" array, even if it's empty.\n",
    "              4. Do not invent or hallucinate any dishes that are not in the MENU.\n",
    "              5. Respond only with the updated order object, nothing else.\n",
    "\n",
    "            Example of an order object:\n",
    "            {json.dumps(example_order, indent=2)}\n",
    "\n",
    "            MENU:\n",
    "            {json.dumps(dishes, indent=2)}\n",
    "\n",
    "            CURRENT ORDER:\n",
    "            {json.dumps(current_order, indent=2)}\n",
    "\n",
    "            USER REQUEST: {query}\n",
    "\n",
    "\n",
    "            Remember:\n",
    "\n",
    "            If the requested dish is not in the MENU, return the current order unchanged.\n",
    "            Customizations should be added as an object with the same structure as in the MENU.\n",
    "            For boolean customizations, use true/false values.\n",
    "            For array customizations, use an array with the selected items.\n",
    "        \"\"\"\n",
    "\n",
    "        response = es_client.options(\n",
    "            request_timeout=60, max_retries=3, retry_on_timeout=True\n",
    "        ).inference.inference(\n",
    "            task_type=\"completion\",\n",
    "            inference_id=\"phi3-completion\",\n",
    "            input=input_content,\n",
    "        )\n",
    "\n",
    "        completion_result = response[\"completion\"][0][\"result\"]\n",
    "        print(f\"Result: \\n {completion_result}\\n\")\n",
    "\n",
    "        current_order = json.loads(response[\"completion\"][0][\"result\"])\n",
    "        print(\n",
    "            f\"The current order status is: \\n {json.dumps(current_order, indent=2)}\\n\"\n",
    "        )\n",
    "\n",
    "    except Exception as e:\n",
    "        print(e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "nelxSToEPTck"
   },
   "source": [
    "## Cleanup\n",
    "\n",
    "Finally, we can delete the resources used to prevent them from consuming resources.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "hIVOVYKxPTck",
    "outputId": "91336554-5b17-4106-812a-1fb85866189b"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stderr",
     "text": [
      "<ipython-input-101-ed0931a48b5f>:2: DeprecationWarning: Passing transport options in the API method is deprecated. Use 'Elasticsearch.options()' instead.\n",
      "  es_client.indices.delete(index=\"lasticco-menu\", ignore=[400, 404])\n",
      "<ipython-input-101-ed0931a48b5f>:5: DeprecationWarning: Passing transport options in the API method is deprecated. Use 'Elasticsearch.options()' instead.\n",
      "  es_client.inference.delete_model(inference_id=\"phi3-completion\", ignore=[400, 404])\n",
      "<ipython-input-101-ed0931a48b5f>:8: DeprecationWarning: Passing transport options in the API method is deprecated. Use 'Elasticsearch.options()' instead.\n",
      "  es_client.inference.delete_model(inference_id=\"elser-embeddings\", ignore=[400, 404])\n"
     ]
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "ObjectApiResponse({'acknowledged': True, 'pipelines': [], 'indexes': []})"
      ]
     },
     "metadata": {},
     "execution_count": 101
    }
   ],
   "source": [
    "# Cleanup - Delete Index\n",
    "es_client.indices.delete(index=\"lasticco-menu\", ignore=[400, 404])\n",
    "\n",
    "# Cleanup - Delete Completions\n",
    "es_client.inference.delete_model(inference_id=\"phi3-completion\", ignore=[400, 404])\n",
    "\n",
    "# Cleanup - Delete Embeddings Endpoint\n",
    "es_client.inference.delete_model(inference_id=\"elser-embeddings\", ignore=[400, 404])"
   ]
  }
 ]
}